/******************************************************************
 * Filename:httpsrv.c
 * Description:http server  Entry function
 * Version:V_1.0	Sept-27-2019
 * Copyright:HISOME <www.hisome.com.>
 * Author:Gaoy
 * EMail:gaoy@hisome.com
 ******************************************************************/

#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include "../mongoose/mongoose.h"
#include "global_common.h"
#include "xeSqlite.h"
#include "src_mgnt.h"

static const char *s_http_port = "12000";
static struct mg_serve_http_opts s_http_server_opts;
static void ev_handlerUrlMap(struct mg_connection *nc, int ev, void *ev_data);
static void handle_sum_call(struct mg_connection *nc, struct http_message *hm);
void websrv_init(struct mg_mgr *mgr);
void websrv_run(struct mg_mgr *mgr);
void getUrlMapStruct(struct http_message *hm,UrlMapStruct *umr,char *remoteIP);


int tiny_http_main()
{
    struct mg_mgr mgr;
    websrv_init(&mgr);
    websrv_run(&mgr);

    return 0;
}

void websrv_init(struct mg_mgr *mgr){
   struct mg_connection *nc;
   struct mg_bind_opts bind_opts;  
   const char *err_str;
   mg_mgr_init(mgr, NULL);
   memset(&bind_opts, 0, sizeof(bind_opts));
   bind_opts.error_string = &err_str;
   nc = mg_bind_opt(mgr, s_http_port, ev_handlerUrlMap, bind_opts);
   if (nc == NULL) {
     xeLOG_ERR("Error starting server on port %s: %s", s_http_port,*bind_opts.error_string);
     exit(1);
   }
   mg_set_protocol_http_websocket(nc);
  s_http_server_opts.enable_directory_listing = "no";
  s_http_server_opts.document_root = "./html";
  xeLOG_NOTICE("Start Restful server on port %s, serving %s", s_http_port,s_http_server_opts.document_root);
}
void websrv_run(struct mg_mgr *mgr){
   while(20190918) {
    mg_mgr_poll(mgr, 50);
  }
  mg_mgr_free(mgr);
}

static void ev_handlerUrlMap(struct mg_connection *nc, int ev, void *ev_data) {
    struct http_message *hm = (struct http_message *) ev_data;
    switch (ev) {
    case MG_EV_HTTP_REQUEST:{
            char *realUrl =NULL;
            // STD_print("\t1 message:\n%s\n\n",hm->message.p);
            // xeLOG_NOTICE("http method:\n%s\n",hm->method.p);
            xeLOG_NOTICE("\t1 uri:\n%s\n\n",hm->uri.p);
            xeLOG_NOTICE("\t1 body:\n%s\n\n",hm->body.p);
            realUrl=strstr(hm->uri.p,HISOME_PREFIX);
            if(realUrl==NULL){
                realUrl=strstr(hm->uri.p,HISOME_PREFIX_NOJSON);    
            }
            if(realUrl!=NULL && 0 == strncmp(realUrl,HISOME_PREFIX_NOJSON,strlen(HISOME_PREFIX_NOJSON))){
                // realUrl:/NOJSON_HISOMEAPI/playback/backUp/setup&userID=3468886&reqType=POST&chanNum=0&task=DOWNLOAD&startTime=2019-12-10%2012:36:10&endTime=2019-12-10%2013:48:36 HTTP/1.1
                #if 1
                    MyHttpPack myhttpReq;
                    memset(&myhttpReq,0,sizeof(myhttpReq));
                    myhttpReq.httpReq.nc=nc;
                    myhttpReq.httpReq.hm=hm;
                    getUrlMapStruct(hm,&myhttpReq.urlmap,inet_ntoa(nc->sa.sin.sin_addr));
                    db_selectUrlMap(myhttpReq);
                    #else
                    mg_serve_http(nc, hm, s_http_server_opts); /* Serve static content */
                    #endif
            }else if(realUrl!=NULL && 0 == strncmp(realUrl,HISOME_PREFIX,strlen(HISOME_PREFIX))){
                MyHttpPack myhttpReq;
                memset(&myhttpReq,0,sizeof(myhttpReq));
                myhttpReq.httpReq.nc=nc;
                myhttpReq.httpReq.hm=hm;
                getUrlMapStruct(hm,&myhttpReq.urlmap,inet_ntoa(nc->sa.sin.sin_addr));
                db_selectUrlMap(myhttpReq);
            }else{
                mg_serve_http(nc, hm, s_http_server_opts); /* Serve static content */
            }
            break;
    }
    default:
        break;
    }

}


void getUrlMapStruct(struct http_message *hm,UrlMapStruct *umr,char *remoteIP){
    char tmpBuf[HISOME_LEN_128]={'\0'};
    char *realUrl_s=NULL;
    char *realUrl_e=NULL;
    umr->_isJson = true;
    if(strstr(hm->uri.p,HISOME_PREFIX_NOJSON)){
        umr->_isJson = false;
        realUrl_s = strstr(hm->uri.p,HISOME_PREFIX_NOJSON);
        realUrl_e = strstr(hm->uri.p,"&userID=");
        memcpy(umr->url, realUrl_s+strlen(HISOME_PREFIX_NOJSON),sizeof(umr->url) - 1 < (realUrl_e - realUrl_s)-strlen(HISOME_PREFIX_NOJSON) ? sizeof(umr->url) - 1 : (realUrl_e - realUrl_s) - strlen(HISOME_PREFIX_NOJSON));
    }else{

        umr->_isJson = true;
        realUrl_s = strstr(hm->uri.p,HISOME_PREFIX);
        realUrl_e = strstr(hm->uri.p," HTTP/1.");
        memcpy(umr->url, realUrl_s+strlen(HISOME_PREFIX),sizeof(umr->url) - 1 < (realUrl_e - realUrl_s)-strlen(HISOME_PREFIX) ? sizeof(umr->url) - 1 : (realUrl_e - realUrl_s) - strlen(HISOME_PREFIX));
    }
    memcpy(umr->ip, remoteIP,strlen(remoteIP) < sizeof(umr->ip) ? strlen(remoteIP) :sizeof(umr->ip));
    // STD_print("umr->url:%s ip:%s",umr->url,umr->ip);
    if(umr->_isJson){
        cJSON *root;
        root=cJSON_Parse(hm->body.p);
        if (!root) {
            xeLOG_NOTICE("Error before: [%s] when cJSON_Parse",cJSON_GetErrorPtr());
            strcpy(tmpBuf,"GET");
        }else{
            strcpy(tmpBuf,cJSON_GetObjectItem(root,"reqType")->valuestring);
            cJSON_Delete(root);
        }
    }else{
        mg_get_http_var(&hm->message,"reqType",tmpBuf,sizeof(tmpBuf));
    }

    if(!strcasecmp(tmpBuf,"GET")){
        umr->method= HTTP_METHOD_GET;
    }else if(!strcasecmp(tmpBuf,"POST")){
        umr->method= HTTP_METHOD_POST;
    }else if(!strcasecmp(tmpBuf,"DELETE")){
        umr->method= HTTP_METHOD_DELETE;
    }else if(!strcasecmp(tmpBuf,"QUERY")){
        umr->method= HTTP_METHOD_QUERY;
    }else{
        umr->method= HTTP_METHOD_GET;
    }
}
